package com.ywjh.inter.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gson.JsonObject;
import com.ywjh.inter.conn.DBConnection;
import com.ywjh.inter.dao.AddressDAO;
import com.ywjh.inter.dao.DocProfileDAO;
import com.ywjh.inter.dao.ProfileDAO;
import com.ywjh.inter.dao.UserBGluTimeDAO;
import com.ywjh.inter.dao.UserFocusDAO;
import com.ywjh.inter.dao.UsersDAO;
import com.ywjh.inter.dao.UsersHXDAO;
import com.ywjh.inter.entity.DocProfileEntity;
import com.ywjh.inter.entity.ProfileEntity;
import com.ywjh.inter.entity.UserAddressEntity;
import com.ywjh.inter.entity.UserFocusEntity;
import com.ywjh.inter.entity.UserPlanTimeEntity;
import com.ywjh.inter.entity.UsersEntity;
import com.ywjh.inter.entity.UsersHXEntity;
import com.ywjh.inter.utils.HTTPHelper;
import com.ywjh.inter.utils.StrUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class UsersService {
	private static UsersService instance;

	private UsersDAO usersDAO;
	private UsersHXDAO usersHXDAO;

	private ProfileDAO profileDAO;
	private DocProfileDAO docProfileDAO;
	private UserBGluTimeDAO userBGluTimeDAO;
	private AddressDAO addressDAO;
	private UserFocusDAO userFocusDAO;

	public static UsersService getInstance() {
		if (instance == null) {
			instance = new UsersService();
			instance.usersDAO = new UsersDAO();
			instance.usersHXDAO = new UsersHXDAO();
			instance.profileDAO = new ProfileDAO();
			instance.userBGluTimeDAO = new UserBGluTimeDAO();
			instance.addressDAO = new AddressDAO();
			instance.docProfileDAO = new DocProfileDAO();
			instance.userFocusDAO = new UserFocusDAO();
		}
		return instance;
	}

	public boolean existPhone(String phone) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			UsersEntity e = usersDAO.findByPhone(conn, phone);
			if (e != null) {
				b = true;
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public static void main(String[] args) throws IOException {

		long t = System.currentTimeMillis();
		JSONObject json = JSONObject.fromObject("{\"act\":\"list_by_disease\",\"data\":{\"doc_id\":\"33\"}}"
				+ "");
		String s = HTTPHelper.postData("http://api.yunyixuehealth.com/interface/doc/list_patient", json, null);
		JSONObject jsonObject=JSONObject.fromObject(s);
		JSONObject d=jsonObject.getJSONObject("d");
		Set<String> set=d.keySet();
		for(String key:set) {
			System.out.print(key+":");
			System.out.println(d.getJSONArray(key).size());
		}
		
		//System.out.println(System.currentTimeMillis() - t);
	}

	public static String getData(String getUrl, Map<String, String> header) throws IOException {
		String result = "";
		HttpURLConnection connection = null;
		try {
			// 创建连接
			URL url = new URL(getUrl);
			connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Content-Type", "application/json");
			connection.setRequestProperty("Accept", "application/json");
			if (header != null) {
				for (String key : header.keySet()) {
					connection.setRequestProperty(key, header.get(key));
				}
			}
			connection.connect();

			// 读取响应
			BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
			String lines;
			StringBuffer sb = new StringBuffer("");
			while ((lines = reader.readLine()) != null) {
				sb.append(lines);
			}
			result = sb.toString();

			reader.close();

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			// 断开连接
			if (connection != null) {
				connection.disconnect();
			}
		}

		return result;
	}

	public int registerUser(UsersEntity u) {
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			conn.setAutoCommit(false);
			u.setLast_login_time(new Timestamp(System.currentTimeMillis()));
			int user_id = usersDAO.insert(conn, u);
			if (user_id > 0) {
				UsersHXEntity hxEntity = new UsersHXEntity();
				hxEntity.setUser_id(user_id);
				hxEntity.setUsername("user_" + user_id);
				String timestamp = System.currentTimeMillis() + "";
				String pwd = timestamp.substring(timestamp.length() - 6);
				hxEntity.setPassword(pwd);
				int hx_id = usersHXDAO.insert(conn, hxEntity);
				if (hx_id > 0) {
					try {
						JSONObject json = HXService.getInstance().regiestUser(hxEntity.getUsername(),
								hxEntity.getPassword(), HXService.getInstance().token());
						if (json != null) {
							conn.commit();
							return user_id;
						} else {
							conn.rollback();
						}
					} catch (IOException e) {
						conn.rollback();
						e.printStackTrace();
					}

				} else {
					conn.rollback();
				}
			} else {
				conn.rollback();
			}
		} catch (ClassNotFoundException | SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DBConnection.close(conn);
		}
		return -1;
	}

	public boolean addProfile(ProfileEntity entity) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			int id = profileDAO.insert(conn, entity);
			if (id > 0) {
				b = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public boolean updateProfile(ProfileEntity entity) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			b = profileDAO.update(conn, entity);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public ProfileEntity getProfileByUserId(int user_id) {
		ProfileEntity e = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			e = profileDAO.findByUserId(conn, user_id);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return e;
	}

	public UsersEntity findUserByPhone(String phone) {
		UsersEntity user = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			user = usersDAO.findByPhone(conn, phone);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return user;
	}

	public UsersEntity findByAccount(String loginname, String password) {
		UsersEntity user = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			user = usersDAO.findByAccount(conn, loginname, password);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return user;
	}

	public List<UsersEntity> searchByKeyword(String keyword) {
		List<UsersEntity> list = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			list = usersDAO.searchByKeyword(conn, keyword);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public UsersHXEntity findHXUserByUserId(int userid) {
		UsersHXEntity hx = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			hx = usersHXDAO.findByUserId(conn, userid);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return hx;
	}

	public UsersEntity findByLoginname(String loginname, String pwd) {
		UsersEntity user = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			user = usersDAO.findByLoginname(conn, loginname, pwd);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return user;
	}

	public UsersEntity findByLoginname(String loginname) {
		UsersEntity user = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			user = usersDAO.findByLoginname(conn, loginname);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return user;
	}

	public UsersEntity findUserById(int id) {
		UsersEntity user = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			user = usersDAO.findById(conn, id);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return user;
	}

	public boolean updateUsers(UsersEntity users) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			b = usersDAO.update(conn, users);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public boolean setUserBGluTime(int userId, List<UserPlanTimeEntity> list) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			conn.setAutoCommit(false);
			userBGluTimeDAO.deleteByUserId(conn, userId);
			b = userBGluTimeDAO.set(conn, list);
		} catch (Exception e1) {
			try {
				conn.rollback();
			} catch (SQLException e) {
				e.printStackTrace();
				e1.printStackTrace();
			}
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DBConnection.close(conn);
		}
		return b;
	}

	public List<UserPlanTimeEntity> getUserBGluTime(int userId) {
		List<UserPlanTimeEntity> list = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			list = userBGluTimeDAO.listByUserId(conn, userId);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public boolean addAddress(ProfileEntity profileEntity, UserAddressEntity addressEntity) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			int id = addressDAO.insert(conn, addressEntity);
			if (id > 0) {
				if (profileEntity.getDefault_address_id() == 0) {
					profileEntity.setDefault_address_id(id);
					profileDAO.update(conn, profileEntity);
				}
				b = true;
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}

		return b;
	}

	public boolean updateAddress(UserAddressEntity addressEntity) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			b = addressDAO.update(conn, addressEntity);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public UserAddressEntity findAddressById(int address_id) {
		UserAddressEntity addressEntity = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			addressEntity = addressDAO.find(conn, address_id);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return addressEntity;
	}

	public List<UserAddressEntity> findAddressByUserId(int user_id) {
		List<UserAddressEntity> list = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			list = addressDAO.listByUserId(conn, user_id);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public DocProfileEntity findDocProfileByUserId(int userId) {
		DocProfileEntity entity = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			entity = docProfileDAO.findByUserId(conn, userId);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return entity;
	}

	public boolean setDocProfile(DocProfileEntity docProfileEntity) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			if (docProfileDAO.findByUserId(conn, docProfileEntity.getUser_id()) != null) {
				b = docProfileDAO.update(conn, docProfileEntity);
			} else {
				b = docProfileDAO.insert(conn, docProfileEntity);
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	// 根据当前时间获得血糖计划ID
	public int getCurrentBgluPlanId(Timestamp time, int user_id) {
		int planId = -1;
		String yyyymmdd = StrUtil.getYYYYMMDD(time);
		List<UserPlanTimeEntity> timeList = UsersService.getInstance().getUserBGluTime(user_id);
		if (timeList.isEmpty()) {
			// get default
			timeList = UsersService.getInstance().getUserBGluTime(-1);
		}
		for (UserPlanTimeEntity timeEntity : timeList) {
			Timestamp start = StrUtil.getTimestampHHMI(yyyymmdd + " " + timeEntity.getStart_hh());
			Timestamp end = StrUtil.getTimestampHHMI(yyyymmdd + " " + timeEntity.getEnd_hh());
			if (start.getTime() <= time.getTime() && time.getTime() < end.getTime()) {
				planId = timeEntity.getPlan_id();
				break;
			}
		}
		return planId;
	}

	public boolean setFocus(int user_id, JSONArray focus_array) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			conn.setAutoCommit(false);
			userFocusDAO.deleteByUserId(conn, user_id);
			List<UserFocusEntity> list = new LinkedList<UserFocusEntity>();
			for (int i = 0; i < focus_array.size(); i++) {
				UserFocusEntity entity = new UserFocusEntity();
				entity.setFriend_id(focus_array.getInt(i));
				entity.setUser_id(user_id);
				entity.setAdd_time(new Timestamp(System.currentTimeMillis()));
				list.add(entity);
			}
			userFocusDAO.insert(conn, list);
			conn.commit();
			b = true;
		} catch (ClassNotFoundException | SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DBConnection.close(conn);
		}
		return b;
	}

	public List<UserFocusEntity> listFocus(int user_id) {
		Connection conn = null;
		List<UserFocusEntity> list = null;
		try {
			conn = DBConnection.getDBConnection();
			list = userFocusDAO.listByUserId(conn, user_id);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public boolean addFocus(int user_id, JSONArray focus_array) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			List<UserFocusEntity> list = new LinkedList<UserFocusEntity>();
			for (int i = 0; i < focus_array.size(); i++) {
				UserFocusEntity entity = userFocusDAO.findByFocus(conn, user_id, focus_array.getInt(i));
				System.out.println("focus==" + entity);
				if (entity == null) {
					entity = new UserFocusEntity();
					entity.setFriend_id(focus_array.getInt(i));
					entity.setUser_id(user_id);
					entity.setAdd_time(new Timestamp(System.currentTimeMillis()));
					list.add(entity);
				}
			}
			userFocusDAO.insert(conn, list);
			b = true;
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public boolean deleteFocus(int user_id, JSONArray focus_array) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			for (int i = 0; i < focus_array.size(); i++) {
				userFocusDAO.deleteByFocus(conn, user_id, focus_array.getInt(i));
			}
			b = true;
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public boolean deleteFocus(int user_id, int friend_id) {
		boolean b = false;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			userFocusDAO.deleteByFocus(conn, user_id, friend_id);
			b = true;
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return b;
	}

	public List<UsersEntity> searchByKeyword(String keyword, int user_id) {
		List<UsersEntity> list = null;
		Connection conn = null;
		try {
			conn = DBConnection.getDBConnection();
			JSONObject resultJson = HXService.getInstance().getFriendList("user_" + user_id,
					HXService.getInstance().token());
			JSONArray friendArray = resultJson.getJSONArray("data");
			List<String> friendIdList = new LinkedList<>();
			for (int i = 0; i < friendArray.size(); i++) {
				String hx_username = friendArray.getString(i);
				int friendID = Integer
						.parseInt(hx_username.substring(hx_username.lastIndexOf("_") + 1, hx_username.length()));
				friendIdList.add(friendID + "");
			}
			String array = StrUtil.List2Str(friendIdList, ",");
			list = usersDAO.searchByKeyword(conn, keyword, array);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			DBConnection.close(conn);
		}
		return list;
	}

	public List<DocProfileEntity> listManagedDocList(int inst_id, int rule_level) {
		List<DocProfileEntity> list = null;
		Connection dbConnection = null;
		try {
			dbConnection = DBConnection.getDBConnection();
			switch (rule_level) {
			case 1:// 主任
				list = docProfileDAO.listDirectorManaged(dbConnection, inst_id, rule_level);
				break;
			default:// 医生及医护
				list = docProfileDAO.listManaged(dbConnection, inst_id, rule_level);
				break;
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			DBConnection.close(dbConnection);
		}
		return list;
	}

}
